package cn.edu.lsu.integratedsurvey.service.impl;

import cn.edu.lsu.integratedsurvey.bean.History;
import cn.edu.lsu.integratedsurvey.bean.LoginRecords;
import cn.edu.lsu.integratedsurvey.bean.User;
import cn.edu.lsu.integratedsurvey.bean.dto.LoginDto;
import cn.edu.lsu.integratedsurvey.bean.dto.UserChangeDto;
import cn.edu.lsu.integratedsurvey.bean.dto.UserRegisterDto;
import cn.edu.lsu.integratedsurvey.bean.vo.HistoryInfoVo;
import cn.edu.lsu.integratedsurvey.bean.vo.LoginVo;
import cn.edu.lsu.integratedsurvey.bean.vo.UserInfoVo;
import cn.edu.lsu.integratedsurvey.exception.SystemException;
import cn.edu.lsu.integratedsurvey.mapper.HistoryMapper;
import cn.edu.lsu.integratedsurvey.mapper.LoginRecordsMapper;
import cn.edu.lsu.integratedsurvey.mapper.UserMapper;
import cn.edu.lsu.integratedsurvey.service.UserService;
import cn.edu.lsu.integratedsurvey.tool.JwtUtil;
import cn.edu.lsu.integratedsurvey.tool.BCryptUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Jasmine-drs
 * @description 针对表【user(用户表)】的数据库操作Service实现
 * @Date 2024-05-01 10:12:36
 */
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

	private final UserMapper userMapper;
	private final BCryptUtil bCryptUtil;
	private final JwtUtil jwtUtil;
	private final LoginRecordsMapper loginRecordsMapper;
	private final HistoryMapper historyMapper;

	public UserServiceImpl(UserMapper userMapper, BCryptUtil bCryptUtil, JwtUtil jwtUtil, LoginRecordsMapper loginRecordsMapper, HistoryMapper historyMapper) {
		this.userMapper = userMapper;
		this.bCryptUtil = bCryptUtil;
		this.jwtUtil = jwtUtil;
		this.loginRecordsMapper = loginRecordsMapper;
		this.historyMapper = historyMapper;
	}

	@Override
	public LoginVo login(LoginDto userLogin) {
		try {
			LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
			wrapper.eq(User::getAccount, userLogin.getAccount());
//		校验用户
			User user = userMapper.selectOne(wrapper);
			if (user == null) {
				throw new SystemException("用户不存在", 400);
			}
			if (log.isDebugEnabled()) {
				log.debug("user: {}", user);
			}
//		校验密码
			if (!bCryptUtil.checkPassword(userLogin.getPassword(), user.getPassword())) {
				throw new SystemException("密码错误", 400);
			}
//			构建jwt
			String token = jwtUtil.createToken(user);
			if (log.isDebugEnabled()) {
				log.debug("登录成功, token: {}", token);
			}
//			构建loginRecords插入jwt记录表
			LoginRecords loginRecords = new LoginRecords();
			loginRecords.setJwt(token);
			loginRecords.setAccount(userLogin.getAccount());
			loginRecords.setPassword(user.getPassword());
//			插入之前先通过账号检查
			LambdaQueryWrapper<LoginRecords> loginRecordsWrapper = new LambdaQueryWrapper<>();
			loginRecordsWrapper.eq(LoginRecords::getAccount, userLogin.getAccount());
			LoginRecords loginRecords1 = loginRecordsMapper.selectOne(loginRecordsWrapper);
//			如果有则删除旧纪录
			if (loginRecords1 != null) {
				loginRecordsMapper.deleteById(loginRecords1.getId());
			}
//			插入新的记录
			loginRecordsMapper.insert(loginRecords);
//			组装vo对象
			LoginVo loginVo = LoginVo.convertToVo(user);
//			手动设置jwt
			loginVo.setJwt(token);
//			手动设置操作员名称
			String operatorName = userMapper.selectOne(new QueryWrapper<User>().eq("id", user.getOperatorId())).getName();
			loginVo.setOperatorName(operatorName);
			return loginVo;
		} catch (Exception e) {
			// 处理可能的数据库异常等
			log.error("登录异常: {}", e.getMessage());
			throw new SystemException(e.getMessage(), 500);
		}
	}

	@Override
	public boolean register(UserRegisterDto userRegisterDto, Integer operatorId) {
		User user = new User();
		user.setAccount(userRegisterDto.getAccount());
		user.setDepartment(userRegisterDto.getDepartment());
		user.setName(userRegisterDto.getName());
		user.setRole(userRegisterDto.getRole());
		user.setOperatorId(operatorId);
//		加密密码，初始密码与账号相同
		user.setPassword(bCryptUtil.hashPassword(userRegisterDto.getAccount()));
		int insert = userMapper.insert(user);
		return insert == 1;
	}

	@Override
	public Page<HistoryInfoVo> getHistoryInfoById(Integer id, Integer pageNumber, Integer pageSize) {
//		查询操作员信息
		User user = userMapper.selectById(id);
		if (user != null) {
//			获取操作员的必要信息
			String operatorName = user.getName();
			String operatorDepartment = user.getDepartment();
//			构造查询条件
			Page<History> historyPage = new Page<>(pageNumber, pageSize);
			LambdaQueryWrapper<History> historyLambdaQueryWrapper = new LambdaQueryWrapper<>();
			historyLambdaQueryWrapper.eq(History::getOperatorName, operatorName)
					.eq(History::getOperatorDepartment, operatorDepartment);
//			获取历史记录列表
			Page<History> historiesPage = historyMapper.selectPage(historyPage, historyLambdaQueryWrapper);
			List<History> histories = historiesPage.getRecords();

//			转化为历史记录Vo对象
			ArrayList<HistoryInfoVo> historyInfoVos = new ArrayList<>();
			for (History history : histories) {
				HistoryInfoVo historyInfoVo = HistoryInfoVo.convertToVo(history);
				historyInfoVo.setOperatorName(operatorName);
				historyInfoVo.setOperatorDepartment(operatorDepartment);
				historyInfoVos.add(historyInfoVo);
			}
//			构造VO分页对象，只有Records不一样，其他都一样
			Page<HistoryInfoVo> historyInfoVoPage = new Page<>(historiesPage.getCurrent(),
					historiesPage.getSize(),
					historiesPage.getTotal());
			historyInfoVoPage.setRecords(historyInfoVos);
			return historyInfoVoPage;
		}
		return new Page<>();
	}

	@Override
	public List<UserInfoVo> getAllUser() {
		List<User> users = userMapper.selectList(null);
		return users.stream().map(UserInfoVo::convertToVO).toList();
	}

	@Override
	public List<UserInfoVo> searchUser(String keyword) {
//		根据账号或姓名搜索管理员
		if (keyword != null) {
			LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
			wrapper.like(User::getAccount, keyword)
					.or()
					.like(User::getName, keyword);
			List<User> users = userMapper.selectList(wrapper);
			return users.stream().map(UserInfoVo::convertToVO).toList();
		}
		return List.of();
	}

	@Override
	public boolean confirmPassword(UserChangeDto userChangeDto) {
		if (userChangeDto.getAccount() != null && userChangeDto.getOldPassword() != null) {
			LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
			wrapper.eq(User::getAccount, userChangeDto.getAccount());
			User user = userMapper.selectOne(wrapper);
			if (user != null) {
				return bCryptUtil.checkPassword(userChangeDto.getOldPassword(), user.getPassword());
			}
			throw new SystemException("用户不存在", 400);
		}
		return false;
	}

	@Override
	public boolean changePassword(UserChangeDto userChangeDto) {
		if (userChangeDto.getAccount() != null && userChangeDto.getNewPassword() != null) {
			LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
			wrapper.eq(User::getAccount, userChangeDto.getAccount());
			User user = userMapper.selectOne(wrapper);
			if (user != null) {
				user.setPassword(bCryptUtil.hashPassword(userChangeDto.getNewPassword()));
				userMapper.updateById(user);
				return true;
			}
			throw new SystemException("用户不存在", 400);
		}
		return false;
	}

	@Override
	public boolean resetPassword(String account) {
//		重置密码为初始秘密，也就是与账号相同
		if (account != null) {
			LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
			wrapper.eq(User::getAccount, account);
			User user = userMapper.selectOne(wrapper);
			if (user != null) {
				user.setPassword(bCryptUtil.hashPassword(user.getAccount()));
				userMapper.updateById(user);
				return true;
			}
			throw new SystemException("用户不存在", 400);
		}
		return false;
	}
}




